/*
 * Copyright (c) 2009 Nathaniel Houghton <nathan@brainwerk.org>
 *                    Robert Kirchgessner <rkirchge@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for
 * any purpose with or without fee is hereby granted, provided that
 * the above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "usart.h"
#include "ui.h"
#include "cmd.h"
#include "mode.h"
 
char *mode_str[] = {
	"ELM Pass-Thru",
	"Logging",
	"Configuration"
};
 
uint8_t
change_mode(struct mode *mode, uint8_t newmode)
{
	if (mode->mode == newmode)
		return 1;

	mode->new_mode = newmode;

	if (mode->mode_update == 0)
		mode->mode_update = 1;

	return 1;
} 

void
change_state(struct mode *mode, uint8_t newstate)
{
	mode->state = newstate;
}

void
mode_seq(struct mode *mode)
{
	if (mode->mode_update == 1) {
		if (mode->state > STATE_0_INIT) {
			mode->state = STATE_FF_END;
			mode->mode_update = 2;
		} else {
			mode->mode = mode->new_mode;
			mode->state = STATE_0_INIT;
			mode->mode_update = 0;
		}
	} else if (mode->mode_update == 2) {
		mode->mode = mode->new_mode;
		mode->state = STATE_0_INIT;
		mode->mode_update = 0;
	}
}

uint8_t
ui_mode_change(struct mode *mode)
{
	uint8_t r;
	uint8_t ignition_down;

	r = 0;

	if (!btn_down(BTN_LCDPRESENT))
		return 0;

	ignition_down = btn_down(BTN_IGNITION);

	if (mode->mode == MODE_LOG) {
		if (!ignition_down) {
			r = change_mode(mode, MODE_CONFIG);
		}
	} else {
		if (ignition_down)
			r = change_mode(mode, MODE_LOG);
	}

	return r;
}

uint8_t
ser_mode_change(struct mode *mode, struct cmd *v)
{
	uint8_t r;
	uint8_t print_ok;

	r = 0;
	print_ok = 0;

	if (v->argc == 3 && !strcmp(v->argv[0], "wems") &&
		!strcmp(v->argv[1], "mode")) {
		if (!strcmp(v->argv[2], "elm")) {
			print_ok = 1;
			r = change_mode(mode, MODE_ELM);
		} else if (!strcmp(v->argv[2], "log")) {
			print_ok = 1;
			r = change_mode(mode, MODE_LOG);
		} else if (!strcmp(v->argv[2], "config")) {
			print_ok = 1;
			r = change_mode(mode, MODE_CONFIG);
		}
	} else if (v->argc == 1 && !strcmp(v->argv[0], "!!!")) {
		print_ok = 1;
		r = change_mode(mode, MODE_CONFIG);
	}

	if (print_ok)
		usart_puts(0, "OK\r\n");

	return r;
}
